# Copyright 2004 Daniel Henninger <jadestorm@nc.rr.com>
# Licensed for distribution under the GPL version 2, check COPYING for details

from twisted.internet import reactor, base
#from twisted.protocols import toc
from tlib import toc
from twisted.python import log
#import twisted.im.tocsupport as ts
from tlib.im import tocsupport as ts
import config
import utils
import debug
import xdb

class AIMHandler(toc.TOCClient):
	def gotConfig(self, mode, buddylist, permit, deny):
		self.session.aimcon = self
		bl = self.getBuddyList()
		if (bl != None):
			self.add_buddy(bl)
		self.signon()
		debug.log("AIMHandler: gotConfig %s for %s" % (self.username,self.session.jabberID))

	def onLine(self):
		debug.log("AIMHandler: onLine")
		tmpjid = config.jid
		if (self.session.registeredmunge):
			tmpjid = tmpjid + "/registered"
		self.session.sendPresence(to=self.session.jabberID, fro=tmpjid)

	def updateBuddy(self,username,online,evilness,signontime,idletime,userclass,away):
		from glue import aim2jid

		debug.log("AIMHandler: updateBuddy %s" % (username))
		buddyjid = aim2jid(username)
		if (away):
			show = "away"
		else:
			show = None
		status = None
		ptype = None
		self.session.sendPresence(to=self.session.jabberID, fro=buddyjid, show=show, status=status, ptype=ptype)
		if (self.session.aimcontacts.count(buddyjid)):
			debug.log("AIMHandler: updateBuddy %s already in contact list" % (buddyjid))
		else:
			debug.log("AIMHandler: updateBuddy appending %s to contact list" % (buddyjid))
			self.session.aimcontacts.append(buddyjid)

	def hearMessage(self, username, message, autoreply):
		from glue import aim2jid
		debug.log("AIMHandler: hearMessage %s %s" % (username, message))

		sourcejid = aim2jid(username)
		text = ts.dehtml(message)
		text = text.decode("utf-8")
		self.session.sendMessage(to=self.session.jabberID, fro=sourcejid, body=text, mtype="chat")

	def hearWarning(self, warnlvl, screenname):
		debug.log("AIMHandler: hearWarning [%s] from %s" % (warnlvl,screenname))

	def hearError(self, errcode, *args):
		debug.log("AIMHandler: hearError code %d" % (errcode))
		tmpjid = config.jid
		if (self.session.registeredmunge):
			tmpjid = tmpjid + "/registered"
		self.session.sendMessage(to=self.session.jabberID, fro=tmpjid, body=toc.STD_MESSAGE[errcode], mtype="chat")
		self.session.removeMe()

	# Helper functions
	def getBuddyList(self):
		debug.log("AIMHandler: getBuddyList %s %s" % (config.jid, self.session.jabberID))
		bl = list()
		result = self.session.pytrans.xdb.request(self.session.jabberID, "aimtrans:roster")
		if (result == None):
			debug.log("AIMHandler: getBuddyList unable to get list, or empty")
			return None

		for child in result.childNodes:
			try:
				if(child.tagName == "buddies"):
					for item in child.childNodes:
						try:
							if(item.tagName == "item"):
								bl.append(item.attributes["name"])
						except AttributeError:
							continue
			except AttributeError:
				continue

		return bl


class AIMConnection:
	def __init__(self, username, password):
		self.username = username
		self.password = password
		self.session.aimcontacts = list()
		self.host = "toc.oscar.aol.com"
		self.port = 9898
		debug.log("AIMConnection: client creation for %s" % (self.session.jabberID))
		#self.handler = AIMHandler(self.username, self.password)
		self.handler = AIMHandler
		self.handler.session = self.session
		self.factory = base.BCFactory(self.handler(self.username, self.password))
		debug.log("AIMConnection: connect tcp")
		self.reactor = reactor.connectTCP(self.host, self.port, self.factory)

		debug.log("AIMConnection: \"%s\" created" % (self.username))
	
	def setAway(self, awayMessage=None):
		debug.log("AIMConnection: setAway %s" % (awayMessage))

		if (not hasattr(self.session, "aimcontacts")):
			return

		if (not hasattr(self.session, "aimcon")):
			return

		awymsg = ""
		if (awayMessage):
			awymsg = awayMessage

		self.session.aimcon.away(awymsg)

	def sendMessage(self, target, message):
		from glue import jid2aim

		scrnname = jid2aim(target)
		#htmlized = ts.html(utils.latin1(message))
		debug.log("AIMConnection: sendMessage %s %s" % (scrnname, message))
		if (hasattr(self.session, "aimcon")):
			self.session.aimcon.say(scrnname, message.encode("cp1252", "replace"))
		else:
			debug.log("AIMConnection: not properly logged in")
			return

	def resendBuddies(self, resource):
		debug.log("AIMConnection: resendBuddies %s" % (resource))
		if (not hasattr(self.session, "aimcontacts")):
			return

		for c in self.session.aimcontacts:
			debug.log("AIMConnection: resending buddy of %s" % (c))
			show = None
			status = None
			ptype = "available"
			self.session.sendPresence(to=self.session.jabberID, fro=c, show=show, status=status, ptype=ptype)

	def getvCard(self, vcard, user):
		debug.log("AIMConnection: getvCard %s" % (user))

	def removeMe(self):
		debug.log("AIMConnection: removeMe")
		if (not hasattr(self.session, "aimcontacts")):
			return

		for c in self.session.aimcontacts:
			debug.log("AIMConnection: sending offline for %s" % (c))
			show = None
			status = None
			ptype = "unavailable"
			self.session.sendPresence(to=self.session.jabberID, fro=c, show=show, status=status, ptype=ptype)

	def jabberSubscriptionReceived(self, to, subtype):
		debug.log("AIMConnection: Session \"%s\" - jabberSubscriptionReceived(\"%s\", \"%s\")" % (self.session.jabberID, to, subtype))

		def updatePresence(ptype): # Convenience
			self.session.sendPresence(to=self.session.jabberID, fro=to, ptype=ptype)

		if(to.find('@') > 0): # For contacts
			from glue import jid2aim

			userHandle = jid2aim(to)
			#ssibuddy = oscar.SSIBuddy(userHandle)
			#ssigroup = oscar.SSIGroup("Buddies")

			if(subtype == "subscribe"):
				# User wants to subscribe to contact's presence
				#def cb(arg=None):
				#	updatePresence("subscribed")

				#self.session.aimcon.addItemSSI(ssibuddy).addCallback(cb)
				pass

			elif(subtype == "subscribed"):
				# The user has granted this contact subscription
				pass

			elif(subtype == "unsubscribe"):
				# User wants to unsubscribe to this contact's presence. (User is removing the contact from their list)
				#def cb(arg=None):
				#	updatePresence("unsubscribed")

				#self.session.aimcon.delItemSSI(ssibuddy).addCallback(cb)
				pass

                        elif(subtype == "unsubscribed"):
                                # The user wants to remove this contact's authorisation. Contact will no longer be able to see user
				pass

                else: # The user wants to change subscription to the transport
                        if(subtype == "subscribe"):
                                updatePresence("subscribed")

                        elif(subtype == "subscribed"):
                                return # Nothing to do

                        elif(subtype == "unsubscribe" or subtype == "unsubscribed"):
                                # They want to unregister. Ok, we can do that
                                jid = self.session.jabberID
				debug.log("Subscriptions: Session \"%s\" is about to be unregistered" % (jid))
				self.session.pytrans.registermanager.removeRegInfo(jid)
				debug.log("Subscriptions: Session \"%s\" has been unregistered" % (jid))
